package com.xuecheng.media.service.impl;

import cn.hutool.core.util.StrUtil;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.aliyuncs.vod.model.v20170321.RefreshUploadVideoResponse;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.commons.constants.MediaConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.MediaDto;
import com.xuecheng.commons.model.dto.MediaQueryDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.dto.VodUploadDto;
import com.xuecheng.commons.model.vo.*;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.media.config.VodTemplate;
import com.xuecheng.media.domain.Media;
import com.xuecheng.media.mapper.MediaMapper;
import com.xuecheng.media.service.MediaService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.web.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalTime;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 媒资信息 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-12-07
 */
@Service
public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements MediaService {

    @Autowired
    private VodTemplate vodTemplate;

    //获取上传凭证
    @Override
    public ResponseResult<VodUploadVo> vodToken(VodUploadDto vodUploadDto) {
        //校验参数
        if (StrUtil.isEmpty(vodUploadDto.getTitle()) || StrUtil.isEmpty(vodUploadDto.getFileName())){
            //文件名、标题必须存在
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        try {
            //获取上传凭证
            CreateUploadVideoResponse response = vodTemplate.createUploadVideo(vodUploadDto.getTitle(), vodUploadDto.getFileName());
            //转为vo对象
            VodUploadVo vodUploadVo = BeanHelper.copyProperties(response, VodUploadVo.class);
            return ResponseResult.okResult(vodUploadVo);
        }catch (Exception e){
            throw new BusinessException(ErrorCode.ALIYUNERROR);
        }
    }

    //刷新上传凭证，获取上传地址
    @Override
    public ResponseResult<VodUploadVo> refreshVodToken(String videoId) {
        //校验参数
        if (StrUtil.isEmpty(videoId)){
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        try {
            //刷新上传凭证
            RefreshUploadVideoResponse response = vodTemplate.refreshUploadVideo(videoId);
            //转为vo
            VodUploadVo vodUploadVo = BeanHelper.copyProperties(response, VodUploadVo.class);
            return ResponseResult.okResult(vodUploadVo);
        }catch (Exception e){
            throw new BusinessException(ErrorCode.ALIYUNERROR);
        }
    }

    //保存媒资
    @Override
    public ResponseResult saveMedia(MediaDto mediaDto) throws Exception {
        //校验参数
        if (StrUtil.isEmpty(mediaDto.getFilename()) || StrUtil.isEmpty(mediaDto.getFileId())){
            //文件名、videoId不能为空
            throw new BusinessException(ErrorCode.PARAMSERROR);
        }
        //dto转为数据库实体
        Media media = BeanHelper.copyProperties(mediaDto, Media.class);
        //补充信息
        GetPlayInfoResponse response = vodTemplate.getPlayInfo(media.getFileId());
        //获取时长
        String duration = response.getPlayInfoList().get(0).getDuration();//单位为秒
        //转为格式
        Float f = Float.parseFloat(duration);
        LocalTime localTime = LocalTime.MIN.plusMinutes(f.longValue());
        //设置时间
        media.setTimelength(localTime.toString());
        //获取播放地址
        String playURL = response.getPlayInfoList().get(0).getPlayURL();
        //设置播放地址
        media.setUrl(playURL);
        //设置上传人
        media.setUsername(AuthInfoHolder.getUserId().toString());
        //设置上传时间
        media.setCreateDate(new Date());
        //设置审核状态  未审核
        media.setAuditStatus(MediaConstants.AUDIT_UNPAST_STATUS);
        //写入数据库
        this.save(media);
        //返回200
        return ResponseResult.okResult();
    }

    //媒资分页+条件查询
    @Override
    public ResponseResult<MediaVo> findByPage(PageRequest pageRequest, MediaQueryDto mediaQueryDto) {
        //构造分页对象
        Page<Media> page = new Page<>(pageRequest.getPageNo(), pageRequest.getPageSize());
        //条件查询
        page=this.lambdaQuery().like(StrUtil.isNotEmpty(mediaQueryDto.getFilename()),Media::getFilename,mediaQueryDto.getFilename())
                .eq(StrUtil.isNotEmpty(mediaQueryDto.getType()),Media::getType,mediaQueryDto.getType())
                .eq(StrUtil.isNotEmpty(mediaQueryDto.getAuditStatus()),Media::getAuditStatus,mediaQueryDto.getAuditStatus())
                .page(page);
        //获取分页结果，转为vo
        List<Media> mediaList = page.getRecords();
        List<MediaVo> mediaVoList = BeanHelper.copyWithCollection(mediaList, MediaVo.class);
        return PageResponseResult.okResult(page.getTotal(),mediaVoList);
    }

    //媒资预览
    @Override
    public ResponseResult<String> preview(Long mediaId) throws Exception {
        //查询媒资数据库
        Media media = this.getById(mediaId);
        /*//根据id到阿里云获取最新播放地址
        GetPlayInfoResponse response = vodTemplate.getPlayInfo(media.getFileId());
        String playURL = response.getPlayInfoList().get(0).getPlayURL();*/
        //获取数据库存储的播放地址
        String playUrl = media.getUrl();
        String timeStr = StrUtil.subBetween(playUrl, "Expires=", "&OSSAccessKeyId");//单位为秒
        long expire = Long.parseLong(timeStr) *1000;
        if (System.currentTimeMillis()>=expire){
            //已经过期，重新获取地址
            GetPlayInfoResponse response = vodTemplate.getPlayInfo(media.getFileId());
            playUrl = response.getPlayInfoList().get(0).getPlayURL();
            //更新数据库记录
            media.setUrl(playUrl);
            this.updateById(media);
        }
        //返回播放地址
        return ResponseResult.okResult(playUrl);
    }

    //媒资删除
    @Override
    public ResponseResult deleteMedia(Long mediaId) throws Exception {
        //查询媒资数据库
        Media media = this.getById(mediaId);
        //判断媒资状态  审核已通过不允许删除
        if (media.getAuditStatus().equals(MediaConstants.AUDIT_PASTED_STATUS)){
            throw new BusinessException(ErrorCode.DELETEERROR);
        }
        //删除阿里云视频
        vodTemplate.deleteVideo(media.getFileId());
        //删除数据库记录
        this.removeById(mediaId);
        //返回200
        return ResponseResult.okResult();
    }

    //课程详情页查询媒资播放地址
    @Override
    public ResponseResult<ResourceVo> mediaUrl(Long mediaId) throws Exception {
        //查询媒资对象
        Media media = this.getById(mediaId);
        //获取数据库存储的播放地址
        String playUrl = media.getUrl();
        String timeStr = StrUtil.subBetween(playUrl, "Expires=", "&OSSAccessKeyId");//单位为秒
        long expire = Long.parseLong(timeStr) *1000;
        if (System.currentTimeMillis()>=expire){
            //已经过期，重新获取地址
            GetPlayInfoResponse response = vodTemplate.getPlayInfo(media.getFileId());
            playUrl = response.getPlayInfoList().get(0).getPlayURL();
            //更新数据库记录
            media.setUrl(playUrl);
            this.updateById(media);
        }
        //封装vo
        ResourceVo resourceVo = new ResourceVo();
        resourceVo.setPlayUrl(playUrl);
        //返回结果
        return ResponseResult.okResult(resourceVo);
    }
}
